﻿using System.Linq;

using Microsoft.WowAddonStudio.Lua.Parser;

using NUnit.Framework;

using LuaParser = Microsoft.WowAddonStudio.Lua.Parser.Parser;
using LuaScanner = Microsoft.WowAddonStudio.Lua.Parser.Scanner;

namespace Microsoft.WowAddonStudio.Lua.Tests.Parser
{
    [TestFixture]
    public class QualifiedNameParserSinkTest : ParserTestBase<LuaParser>
    {
        private QualifiedNameParserSink parserSink;

        public override void SetUp()
        {
            base.SetUp();

            parser.Sink = parserSink = new QualifiedNameParserSink();
        }

        [Test]
        public void QualifiedNameTest()
        {
            // Set the source to a partial method call
            parser.SetSource("foo.bar:");

            // Enable finding names
            parserSink.FindNames = true;

            // Assert the parser
            this.AssertParse();

            // Assert that one qualified name was pushed into the sink
            Assert.AreEqual(1, parserSink.QualifiedNames.Count());

            // Assert the qualified name by all possible positions
            for (int i = 1; i <= "foo.bar".Length; i++)
            {
                var qualifiedName = parserSink.GetQualifiedName(0, i);

                Assert.IsNotNull(qualifiedName);
                Assert.AreEqual("foo.bar", qualifiedName.ToString());
            }
        }

        [Test]
        public void MultipleQualifiedNamesTest()
        {
            // Set the source to a partial method call
            parser.SetSource(@"function Frame1:OnLoad() end
Frame1:");

            // Enable finding names
            parserSink.FindNames = true;

            // Assert the parser
            this.AssertParse();

            // Assert that one qualified name was pushed into the sink
            Assert.AreEqual(2, parserSink.QualifiedNames.Count());

            // Assert the second qualified name by all possible positions
            for (int i = 1; i <= "Frame1".Length; i++)
            {
                var qualifiedName = parserSink.GetQualifiedName(1, i);

                Assert.IsNotNull(qualifiedName);
                Assert.AreEqual("Frame1", qualifiedName.ToString());
            }
        }

        [Test]
        public void QualifiedMethodNameTest()
        {
            // Set the source to a partial method call
            parser.SetSource("Frame1:Show(");

            // Enable finding names
            parserSink.FindNames = true;

            // Assert the parser
            this.AssertParse();

            // Assert that one qualified name was pushed into the sink
            Assert.AreEqual(1, parserSink.QualifiedNames.Count());

            var qualifiedName = parserSink.GetQualifiedName(0, 11);

            Assert.IsNotNull(qualifiedName);
            Assert.AreEqual("Frame1.Show", qualifiedName.ToString());
            Assert.AreEqual("Frame1", qualifiedName.Unqualify(true).ToString());
            Assert.AreEqual("Show", qualifiedName.UnqualifiedIdentifier.Name);
        }
    }
}
